package com.yuge.snake.role;

import com.yuge.snake.common.Direction;
import com.yuge.snake.common.GameConst;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Created by Mrper on 15-11-24.
 */
public class Snake extends Thread{

    public interface OnSnakeMoveListener{
        void onMove();
        void onPreviewNextHeader(MapBlock headerBlock);
    }

    public Direction direction = Direction.RIGHT;

    public ArrayList<MapBlock> body = new ArrayList<>();

    public boolean isAutoMove = false;//是否自动移动

    public boolean isAlive = false;//是否存活

    private OnSnakeMoveListener listener;

    public Snake(){
        resetSnake();//重置贪吃蛇
    }

    /**
     * 重置贪吃蛇
     */
    public void resetSnake(){
        body.clear();//清空所有数据对象
        body.addAll(Arrays.asList(
                new MapBlock(2,0),
                new MapBlock(1,0),
                new MapBlock(0,0)
        ));
        direction = Direction.RIGHT;
        isAlive = true;//默认存活
        isAutoMove = true;//自动移动
    }

    /**  检测输入的方向是否合法 **/
    private boolean checkNewDirection(Direction direction){
        if(this.direction == Direction.LEFT){
            if(direction == Direction.RIGHT)
                return false;
        }
        if(this.direction == Direction.RIGHT){
            if(direction == Direction.LEFT)
                return false;
        }
        if(this.direction == Direction.UP){
            if(direction == Direction.DOWN)
                return false;
        }
        if(this.direction == Direction.DOWN){
            if(direction == Direction.UP)
                return false;
        }
        try {
            MapBlock mapBlock = getNextHeaderBlock(direction, (MapBlock) body.get(0).clone());
            if(listener!=null) listener.onPreviewNextHeader(mapBlock);
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 去往方向
     * @param direction
     */
    public void goDirection(Direction direction){
        if(!checkNewDirection(direction)) return;
        int len = body.size();
        try {
            MapBlock preBlock = (MapBlock) (body.get(0).clone());
            //改变除第一个坐标外的其他坐标
            for (int i = 1; i < len; i++) {
                try {
                    MapBlock curBlock = (MapBlock) (body.get(i).clone());
                    body.get(i).x = preBlock.x;
                    body.get(i).y = preBlock.y;
                    preBlock = curBlock;//赋值前一个block
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        getNextHeaderBlock(direction,body.get(0));
        this.direction = direction;
    }

    /**
     * 获得下一步的坐标值
     * @param direction
     * @param firstBlock
     * @return
     */
    private MapBlock getNextHeaderBlock(Direction direction,MapBlock firstBlock){
        //第一个坐标发生变化
        switch (direction) {
            case LEFT:
                firstBlock.x -= 1;
                if(firstBlock.x < 0)
                    firstBlock.x = GameConst.MAX_X-1;
                break;
            case RIGHT:
                firstBlock.x += 1;
                if(firstBlock.x >= GameConst.MAX_X)
                    firstBlock.x = 0;
                break;
            case UP:
                firstBlock.y -= 1;
                if(firstBlock.y < 0)
                    firstBlock.y = GameConst.MAX_Y-1;
                break;
            case DOWN:
                firstBlock.y += 1;
                if(firstBlock.y >= GameConst.MAX_Y)
                    firstBlock.y = 0;
                break;
        }
        return firstBlock;
    }

    /**
     * 是否游戏结束（条件：自己咬住自己的身体）
     * @return
     */
    public boolean isGameOver(MapBlock nextHeaderBlock){
         for(int i=1;i<body.size();i++){
             MapBlock curBlock = body.get(i);
             if(curBlock.x == nextHeaderBlock.x && curBlock.y == nextHeaderBlock.y) {
                 isAlive = false;//游戏结束
                 isAutoMove = false;
                 return true;
             }
         }
        return false;
    }

    /**
     * 设置贪吃蛇自动移动的事件监听
     * @param listener
     */
    public void setOnSnakeMoveListener(OnSnakeMoveListener listener){
        this.listener = listener;
    }

    /**  贪吃蛇根据方向自动移动  **/
    public void autoMove(){
        goDirection(direction);//自动切换坐标
    }

    @Override
    public void run() {
        while(isAlive){
            if(isAutoMove){
                if(listener!=null) listener.onMove();
                try {
                    Thread.sleep(1500);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

}
